<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>文件管理器</title>
		<style type="text/css">
			html,
			body {
				padding: 0;
				margin: 0;
			}

			#App {
				background: transparent;
				width: 100vw;
				height: 100vh;
				display: flex;
				flex-direction: column;
			}

			#App .mask {
				background: rgba(0, 0, 0, .4);
				flex: 1;
				z-index: 12;
			}

			.file-content {
				z-index: 12;
				height: 60px;
				background: #fff;
				display: flex;
				justify-content: center;
				align-items: center;
				position: fixed;
				bottom: 0;
				left: 0;
				width: 100%;
			}

			.btn {
				position: relative;
			}

			.btn .btn-bg {
				background: #0066CC;
				color: #fff;
				width: 100%;
				border-radius: 5px;
				padding: 8px 10px;
				border: 0;
			}

			.btn .file {
				position: absolute;
				left: 0;
				right: 0;
				top: 0;
				bottom: 0;
				width: 100%;
				opacity: 0;
			}

			.tis {
				position: fixed;
				width: 100%;
				height: 100%;
				align-items: center;
				justify-content: center;
				z-index: 12;
				display: none;
			}

			.tis-content {
				width: 60%;
				background-color: #fff;
				padding: 20px 0;
				border-radius: 5px;
				display: flex;
				flex-direction: column;
				align-items: center;
			}

			.tis-content .tis-content-image {
				width: 60px;
				height: 60px;
			}

			.tis-content .tis-content-image img {
				width: 100%;
				height: 100%;
				animation: loading-android 2s linear infinite;
			}

			.tis-content .tis-progress {
				margin: 10px 0;
			}
			.tis-content .tis-text {
				font-size: 16px;color: #888;
			}
			.cancel-btn {
				background: #e3e3e3;
				color: #898989;
				border: 0;
				border-radius: 5px;
			}
			@keyframes loading-android {
				0% {
					transform: rotate(0deg);
				}

				100% {
					transform: rotate(360deg);
				}
			}
		</style>
	</head>
	<body>
		<div id="App">
			<div class="mask" @click="closeCurrentWebview"></div>
			<div class="tis" :style="{display:showUp?'flex':'none'}">
				<div class="tis-content">
					<div class="tis-content-image">
						<img src="../images/loading.png">

					</div>
					<div class="tis-text">{{text}}</div>
					<div class="tis-progress">
						{{progress}}
					</div>
					<div class="cancel">
						<button type="button" class="cancel-btn" @click="cancelUP">取消上传</button>
					</div>
				</div>
			</div>

			<div class="file-content">
				<div class="btn">
					<button type="button" class="btn-bg">打开文件管理器</button>
					<input ref="referenceUpload" class="file" type="file" multiple="multiple" @change="changeFile($event)"/>
				</div>
			</div>
		</div>
		<!-- uni 的 SDK -->
		<script type="text/javascript" src="../js/uni.webview.1.5.2.js">
		</script>
		<script type="text/javascript" src="../js/vue.js"></script>
		<script type="text/javascript" src="../js/mui.min.js"></script>
		<script type="text/javascript" src="../js/global.js"></script>
		<!-- <script type="text/javascript" src="../js/wps/web-office-sdk-v1.1.2.umd.js"></script> -->
		<script type="text/javascript">
			// 为了解决uni-app 的web-view组件中加载mui开发的H5页面时，点击返回报错Uncaught ReferenceError: mui is not defined at __uniappview.html:1
			mui.init({
				keyEventBind: {
					backbutton: false //关闭back按键监听
				}
			});
			document.addEventListener('UniAppJSBridgeReady', function() {
				let that, xhr
				new Vue({
					el: '#App',
					data: {
						showUp: false, //是否显示上传进度
						progress: '', //进度条
						num:0,//当前上传的第几个文件
						files:[],//当前选择的所有文件
						text:''
					},
					mounted() {
						that = this
					},
					methods: {
						//取消上传
						cancelUP() {
							xhr.abort()
							//关闭当前webview
							that.closeCurrentWebview()
						},
						//关闭当前webview
						closeCurrentWebview() {
							plus.webview.currentWebview().close();
						},
						//限制上传文件格式
						restrictFormatUploaded(name, filetypes = ["jpg", "jpeg", "png", "rar", "txt", "zip",
							"doc", "ppt", "xls", "pdf", "docx", "xlsx", "mp4", "wmv", "avi", "mp3", "m4a",
							"wma",
							"JPG", "JPEG", "PNG", "RAR", "TXT", "ZIP", "DOC", "PPT", "XLS", "PDF", "DOCX",
							"XLSX", "MP4", "WMV", "AVI", "MP3", "M4A", "WMA"
						]) {
							let mun = name.lastIndexOf('.')
							let sliceName = name.slice(mun+1, name.length)
							let onoff = filetypes.some(res => res==sliceName)
							return onoff
						},
						//选取文件
						changeFile(event) {
							that.num=0
							that.files=event.target.files
							that.limitFn()
						},
						limitFn(){
							if(that.num>that.files.length||that.num==that.files.length){
								//console.log('已经上传完了');
								setTimeout(()=>{
									//关闭当前webview
									that.closeCurrentWebview()
								},1000)
								return
							}
							that.text=`正在上传第${that.num+1}个文件`
							that.progress = '请稍后..';
							let {
								url,
								key,
								header,
								formData,
								filetypes,
								crossDomain
							} = plus.webview.currentWebview();

							//上传成功后记得置空value否则不触发change事件 通过this.$refs.referenceUpload.value=null
							//限制上传文件格式
							let onoff = that.restrictFormatUploaded(that.files[that.num].name, filetypes)
							if (!onoff) {
								plus.nativeUI.toast('不支持的上传文件类型');
								that.text=`不支持的上传文件类型`
								this.$refs.referenceUpload.value = null
								setTimeout(()=>{
									//关闭当前webview
									that.closeCurrentWebview()
								},1000)
								return
							}
							// if (that.files[that.num].size > (1024 * 1024 * 10)) {
							// 	plus.nativeUI.toast('单个文件请勿超过10M,请重新上传');
							// 	that.text=`单个文件请勿超过10M,请重新上传`
							// 	this.$refs.referenceUpload.value = null
							// 	setTimeout(()=>{
							// 		//关闭当前webview
							// 		that.closeCurrentWebview()
							// 	},1000)
							// 	return;
							// }
							that.showUp = true
							//判断提交时是否为ios，如果是ios再判断是否跨域，如果跨域就用beas64上传
							that.CheckCrossDomain(that.files[that.num], url, key, header, formData, crossDomain)
						},
						//判断提交时是否为ios，如果是ios再判断是否跨域，如果跨域就用beas64上传
						CheckCrossDomain(file, url, key, header, formData, crossDomain) {
							if(plus.os.name=='Android'){
								that.createUpload(file, url, key,header,formData);
								return
							}
							xhr = new XMLHttpRequest();
							xhr.open("POST", crossDomain.src1, true);
							//设置请求头
							for (let keys in header) {
								xhr.setRequestHeader(keys, header[keys]);
							}
							xhr.onreadystatechange = async (ev) => {
								if (xhr.readyState == 4) {
									if (xhr.status == 0) { //说明跨域了
										//console.log('说明跨域了');
										url = crossDomain.src2
										await that.muiUpload(file, url, key, header, formData)
									} else if (xhr.status == 200) { //说明没跨越
										//console.log('说明没跨越');
										that.createUpload(file, url, key, header, formData);
									}

								}
							};
							xhr.send();
						},
						//ios上传跨域（WKWebview环境，只能使用plus.net.XMLHttpRequest解决跨域），但是需要注意上传的参数必须为string，无法使用formData
						async muiUpload(file, url, key = 'file', headers = {}, data = {}){
							let base64= await that.blobToBase64(file)
							//console.log(file.size);
							let req={
									filename: file.name,
									base64code: base64,
									filesize:file.size
								}
							let res= await that.muiAjax(req,url,headers)
							if(res.code == 200){
								that.progress = '上传成功';
								location.href =
									`callback?fileName=${escape(file.name)}&id=${escape(JSON.stringify(res))}`;
								//如果还有文件继续上传
								that.num++
								//休眠1秒
								that.sleep(1000)

								that.limitFn()
							}else{
								plus.nativeUI.toast(res.msg);
								that.progress = res.msg;
							}

						},

						createUpload(file, url, key = 'file', header = {}, data = {}) {
							//console.log(url);
							if (!url) {
								return;
							}
							let formData = new FormData();
							formData.append(key, file);
							for (let keys in data) {
								formData.append(keys, data[keys]);
							}
							xhr = new XMLHttpRequest();
							xhr.open("POST", url, true);
							//设置请求头
							for (let keys in header) {
								xhr.setRequestHeader(keys, header[keys]);
							}
							//监听进度条
							xhr.upload.addEventListener("progress", function(event) {
								if (event.lengthComputable) {
									that.progress = '努力上传中..' + Math.ceil(event.loaded * 100 / event
										.total) + "%";
								}
							}, false);
							xhr.ontimeout = function() {
								// xhr请求超时事件处理
								that.progress = '请求超时';
								setTimeout(() => {
									that.showUp = false
									//关闭当前webview
									that.closeCurrentWebview()
								}, 1000);
							};
							xhr.onreadystatechange = async (ev) => {
								if (xhr.readyState == 4) {
									if (xhr.status == 200) {
										if (JSON.parse(xhr.responseText).code == 200) {
											that.progress = '上传成功';
											location.href =
												`callback?fileName=${escape(file.name)}&id=${escape(xhr.responseText)}`;
											//如果还有文件继续上传
											that.num++
											that.sleep(1000)
											that.limitFn()
										} else {
											plus.nativeUI.toast(JSON.parse(xhr.responseText).msg);
											that.progress = JSON.parse(xhr.responseText).msg;
										}

									} else {
										that.progress = '上传失败了';
									}
								}
							};
							xhr.send(formData);
						},
						blobToBase64(blob) {
							return new Promise((resolve, reject) => {
								const fileReader = new FileReader();
								fileReader.readAsDataURL(blob);
								fileReader.onload = (e) => {
									var dataBase64 = e.target.result.split(";base64,")[1]; //base64文件内容
									resolve(dataBase64);
								};
								fileReader.onerror = () => {
									reject(new Error('blobToBase64 error'));
								};
							});
						},
						muiAjax(data,url,headers={}){
							return new Promise((resolve, reject) => {
								mui.ajax(url,{
									data,
									dataType:'json',//服务器返回json格式数据
									type:'post',//HTTP请求类型
									timeout:20000,//超时时间设置为10秒；
									headers:{'Content-Type':'application/json',...headers},
									success:function(res){
										resolve(res)
									},
									error:function(xhr,type,errorThrown){
										//异常处理；
										//console.log(type);
										reject(type)
									}
								});
							});
						},
						//JS睡眠sleep()
						sleep(numberMillis) {
						    var now = new Date();
						    var exitTime = now.getTime() + numberMillis;
						    while (true) {
						        now = new Date();
						        if (now.getTime() > exitTime){
						            return;
						        }
						    }
						}
					}
				})
			});
		</script>
	</body>
</html>
